//! # Token Definition Module
//!
//! This module defines all token types used in the SysY language compiler.
//! Tokens are the basic units of lexical analysis, representing various lexical elements in source code.
//!
//! # Main Contents
//!
//! - `Token` enum: Defines all supported token types
//! - `Display` implementation: Provides string representation of tokens

use std::fmt;

/// Token type enumeration for the SysY language
///
/// Defines all possible lexical unit types in the SysY language, including keywords, operators, delimiters, identifiers, and constants.
///
/// # Token Categories
///
/// ## Keywords
/// - `Const`, `Int`, `Void`: Type keywords
/// - `If`, `Else`, `While`: Control flow keywords  
/// - `Break`, `Continue`, `Return`: Jump keywords
///
/// ## Operators
/// - Arithmetic operators: `Plus`, `Minus`, `Mul`, `Div`, `Mod`
/// - Comparison operators: `Eq`, `Neq`, `Lt`, `Gt`, `Le`, `Ge`
/// - Logical operators: `Not`, `And`, `Or`
/// - Assignment operator: `Assign`
///
/// ## Delimiters
/// - Parentheses: `LParen`, `RParen`, `LBrace`, `RBrace`, `LBrackt`, `RBrackt`
/// - Others: `Comma`, `Semicolon`
///
/// ## Literals
/// - `Ident(String)`: Identifier, containing the specific identifier name
/// - `Integer(i64)`: Integer constant, containing the specific numeric value
#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    Const,
    Int,
    Void,
    If,
    Else,
    While,
    Break,
    Continue,
    Return,
    Plus,
    Minus,
    Mul,
    Div,
    Mod,
    Assign,
    Eq,
    Neq,
    Lt,
    Gt,
    Le,
    Ge,
    Not,
    And,
    Or,
    LParen,
    RParen,
    LBrace,
    RBrace,
    LBrackt,
    RBrackt,
    Comma,
    Semicolon,
    Ident(String),
    Integer(i64),
}

/// Provides standard string representation for each token type, mainly used for debug output and error reporting.
impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Token::Const => write!(f, "CONST"),
            Token::Int => write!(f, "INT"),
            Token::Void => write!(f, "VOID"),
            Token::If => write!(f, "IF"),
            Token::Else => write!(f, "ELSE"),
            Token::While => write!(f, "WHILE"),
            Token::Break => write!(f, "BREAK"),
            Token::Continue => write!(f, "CONTINUE"),
            Token::Return => write!(f, "RETURN"),
            Token::Plus => write!(f, "PLUS"),
            Token::Minus => write!(f, "MINUS"),
            Token::Mul => write!(f, "MUL"),
            Token::Div => write!(f, "DIV"),
            Token::Mod => write!(f, "MOD"),
            Token::Assign => write!(f, "ASSIGN"),
            Token::Eq => write!(f, "EQ"),
            Token::Neq => write!(f, "NEQ"),
            Token::Lt => write!(f, "LT"),
            Token::Gt => write!(f, "GT"),
            Token::Le => write!(f, "LE"),
            Token::Ge => write!(f, "GE"),
            Token::Not => write!(f, "NOT"),
            Token::And => write!(f, "AND"),
            Token::Or => write!(f, "OR"),
            Token::LParen => write!(f, "L_PAREN"),
            Token::RParen => write!(f, "R_PAREN"),
            Token::LBrace => write!(f, "L_BRACE"),
            Token::RBrace => write!(f, "R_BRACE"),
            Token::LBrackt => write!(f, "L_BRACKT"),
            Token::RBrackt => write!(f, "R_BRACKT"),
            Token::Comma => write!(f, "COMMA"),
            Token::Semicolon => write!(f, "SEMICOLON"),
            Token::Ident(_) => write!(f, "IDENT"),
            Token::Integer(_) => write!(f, "INTEGER_CONST"),
        }
    }
}
